﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing;
using System.Reflection;

namespace LightEngine
{
    namespace VisualTools
    {
        namespace CustomControls
        {
            /// <описание класса public class ColorComboBox : ComboBox>
            /// Версия класса 1.0
            /// Автор(ы): Ушаков Михаил
            /// Класс является пользовательским элементом управления и прредназначен для вывода
            /// в выпадающий список образцов цвтов из перечисления Color.
            /// Элементы класса:
            /// 1. Константы класса:
            /// а) private const Int16 ColorComboStep = 10; расстояние между элементами-экземплярами
            ///    цвета .
            /// б) private const Int16 ColorComboMargin = 3; отстут от верхней и нижней границы. 
            /// 2. Поля класса:
            ///    отсутствуют.
            /// 3. Методы класса:
            /// а) public ColorComboBox()конструктор класса, установка стиля выпадающего скиспка.
            /// б) private void FillWithColors() заполнение внутренней структуры данных в ComboBox 
            ///    элементами перечисления из Color.
            /// в) protected override void OnDrawItem(DrawItemEventArgs Args) обработчик события 
            ///    перерисовки класса.
            /// г) private void DrawColor(DrawItemEventArgs Args, Color DrawingColor, ref Int16 NextXValue)
            ///    рисования экземпляра цвета DrawingColor из внутренней структуры данных ComboBox.
            /// д) DrawText(DrawItemEventArgs Args, Color DrawingColor, Int16 NextXValue) функция осуществляет
            ///    вывод названия цвета (имя цвета) в позицию NextXValue, получаемую в NextXValue.
            /// 4. Свойства и индексаторы класса:
            /// а) public Color SelectedColor свойство для чтения и записи, предназначенное для чтения
            ///    установки текущего выбранного элемента.
            /// </описание класса public class ColorComboBox : ComboBox>
            public class ColorComboBox : ComboBox
            {
                private const Int16 ColorComboStep = 10;
                private const Int16 ColorComboMargin = 3;

                public ColorComboBox()
                {
                    DrawMode = DrawMode.OwnerDrawFixed;
                    DropDownStyle = ComboBoxStyle.DropDownList;
                    FillWithColors();
                }

                private void FillWithColors()
                {
                    Items.Clear();
                    foreach (Color ColorSamples in typeof(Color).GetProperties(BindingFlags.Static |
                             BindingFlags.Public).Where(c => c.PropertyType == typeof(Color)).Select(c => (Color)c.GetValue(c, null)))
                    {
                        Items.Add(ColorSamples);
                    }
                }

                protected override void OnDrawItem(DrawItemEventArgs Args)
                {
                    if (Args.Index >= 0)
                    {
                        Color color = (Color)this.Items[Args.Index];
                        Int16 NextX = 0;
                        Args.Graphics.FillRectangle(new SolidBrush(Args.BackColor), Args.Bounds);
                        DrawColor(Args, color, ref NextX);
                        DrawText(Args, color, NextX);
                    }
                    else
                        base.OnDrawItem(Args);
                }

                private void DrawColor(DrawItemEventArgs Args, Color DrawingColor, ref Int16 NextXValue)
                {
                    Int16 Width = (Int16)(Args.Bounds.Height * 2 - ColorComboStep);
                    Rectangle ColorRect = new Rectangle(Args.Bounds.X + ColorComboMargin,
                                                        Args.Bounds.Y + ColorComboMargin,
                                                        Width, Args.Bounds.Height - (ColorComboMargin + 2));
                    Args.Graphics.FillRectangle(new SolidBrush(DrawingColor), ColorRect);

                    NextXValue = (Int16)(Width + ColorComboStep);
                }

                private void DrawText(DrawItemEventArgs Args, Color DrawingColor, Int16 NextXValue)
                {
                    Args.Graphics.DrawString(DrawingColor.Name, Args.Font,
                                             new SolidBrush(Args.ForeColor),
                                             new PointF(NextXValue, Args.Bounds.Y + (Args.Bounds.Height - Args.Font.Height) / 2));
                }

                public Color SelectedColor
                {
                    get
                    {
                        if (SelectedItem != null)
                            return (Color)SelectedItem;
                        return Color.Black;
                    }
                    set
                    {
                        Color SetColor = value;
                        if (Enum.IsDefined(typeof(Color), SetColor))
                        {
                            SelectedItem = SetColor;
                        }
                    }
                }
            }
        }
    }
}

